﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using WarehouseManagement.Presenters.Export;
using WarehouseManagement.ViewModels.Export;
using WarehouseManagement.BusinessLogic.DTO;
using WarehouseManagement.Views.Customer;
using WarehouseManagement.Views.Merchandise;


namespace WarehouseManagement.Views.Export
{
    public partial class NewEditExport : XtraForm, IView<NewEditExportPresenter>, INewEditExportViewModel
    {
        private NewEditExportPresenter _presenter;
        public enum EditMode { New, EditExisting }
        private EditMode _editMode;
        private bool _dataChanged;
        private bool _dataSaved;
        public NewEditExportPresenter.ExportSaved OnExportSaved;

        public NewEditExport(EditMode mode)
        {
            InitializeComponent();
            _editMode = mode;
            _presenter = SetupPresenter();
        }

        public NewEditExportPresenter SetupPresenter()
        {
            var p = new NewEditExportPresenter();
            p.RegisterViewModel(this);
            return p;
        }




        public string Notes
        {
            get
            {
                return txtNotes.Text;
            }
            set
            {
                txtNotes.Text = value;
            }
        }

        public int MerchandiseId { get; set; }
        private void ExportNew_Load(object sender, EventArgs e)
        {
            btnCreateNewExportNumber.Enabled = (_editMode != EditMode.New);
            txtExportDate.Properties.MaxValue = DateTime.Now;
            _presenter.InitializeView();
            HandleControls();
            //grvExportList.OptionsView.AllowCellMerge = true;
            if (_editMode == EditMode.EditExisting)
            {
                _presenter.LoadExportInfo();
                _presenter.LoadExportList();
            }
        }

        private void HandleControls()
        {

            btnDelete.Enabled = (this.SelectedExportItem != Guid.Empty);
            if (_editMode == EditMode.New)
            {
                btnSave.Enabled = this.ExportDetails.Count() > 0;
                //txtExportDate.Enabled = true;
            }
            else
            {
                //txtExportDate.Enabled = false;
            }

        }

        private void txtSelectMerchandise_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            _presenter.SelectMerchandise();
        }


        private void txtQuantity_EditValueChanged(object sender, EventArgs e)
        {

        }

        private void txtExportPrice_EditValueChanged(object sender, EventArgs e)
        {

        }

        private void btnAddExportItem_Click(object sender, EventArgs e)
        {
            _presenter.Export();
        }



        private void txtNotes_EditValueChanged(object sender, EventArgs e)
        {

        }

        public IEnumerable<CustomerDTO> CustomerList
        {
            get
            {
                return lkCustomer.Properties.DataSource as IEnumerable<CustomerDTO>;
            }
            set
            {
                lkCustomer.Properties.DataSource = value;
                lkCustomer.Properties.DisplayMember = "FullName";
                lkCustomer.Properties.ValueMember = "Id";
                lkCustomer.Properties.PopupFormSize = new System.Drawing.Size() { Width = 700 };
            }
        }

        public Guid ExportId
        {
            get
            {
                return Guid.Parse(this.Tag.ToString());
            }
            set
            {
                this.Tag = value;
            }
        }

        public DateTime ExportDate
        {
            get
            {
                return txtExportDate.DateTime;
            }
            set
            {
                txtExportDate.DateTime = value;
            }
        }

        public string ExportReason
        {
            get
            {
                return txtReason.Text;
            }
            set
            {
                txtReason.Text = value;
            }
        }

        public BindingList<ExportDetailDTO> ExportDetails
        {
            get
            {
                return grdExportList.DataSource as BindingList<ExportDetailDTO>;
            }
            set
            {
                grdExportList.DataSource = value;
            }
        }

        private void lkCustomer_EditValueChanged(object sender, EventArgs e)
        {
            var obj = lkCustomer.GetSelectedDataRow() as CustomerDTO;
            if (obj == null) return;
            Address = obj.Address;
            Mobile = obj.Mobile;
        }


        public string Address
        {
            get
            {
                return txtAddress.Text;
            }
            set
            {
                txtAddress.Text = value;
            }
        }

        public string Mobile
        {
            get
            {
                return txtMobile.Text;
            }
            set
            {
                txtMobile.Text = value;
            }
        }


        public string ExportNumber
        {
            get
            {
                return txtExportNumber.Text;
            }
            set
            {
                txtExportNumber.Text = value;
            }
        }


        public IEnumerable<dynamic> MerchandiseList
        {
            get
            {
                return ipeMerchandiseLookup.DataSource as IEnumerable<dynamic>;
            }
            set
            {
                ipeMerchandiseLookup.DataSource = value;
                ipeMerchandiseLookup.DisplayMember = "MerchandiseName";
                ipeMerchandiseLookup.ValueMember = "Id";
                ipeMerchandiseLookup.PopupFormSize = new System.Drawing.Size() { Width = 900 };
            }
        }

        private void ipeMerchandiseLookup_EditValueChanged(object sender, EventArgs e)
        {
            var edit = sender as GridLookUpEdit;
            //var view = edit.Properties.View as DevExpress.XtraGrid.Views.Grid.GridView;

            var fr = GetFocusRow();

            var selectedItem = (dynamic)edit.GetSelectedDataRow();
            fr.OriginalPrice = selectedItem.OriginPrice;

            fr.AvailableExportQuantity = selectedItem.AvailableQuantity;

        }

        private void grvExportList_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)
        {
            if (e.RowHandle == -2147483648 || e.RowHandle == -2147483647)
                return;
            e.Info.DisplayText = (e.RowHandle + 1).ToString();
        }

        private void grvExportList_ValidateRow(object sender, DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs e)
        {
            var errorList = ValidateExportDetailRow();
            e.Valid = errorList.Count() == 0;
            if (errorList.Count() > 0)
            {
                var errMsg = string.Join("\n", errorList);
                e.ErrorText = errMsg;
            }
        }

        private IEnumerable<string> ValidateExportDetailRow()
        {
            var focusRow = GetFocusRow();
            if (focusRow.MerchandiseId == 0)
                yield return "Bạn chưa chọn mặt hàng";

            //var totalExportQty = GetTotalExportQuantity(focusRow.MerchandiseId);
            //if (totalExportQty > focusRow.AvailableExportQuantity)
            //{
            //    yield return "Số lượng xuất vượt quá số lượng trong kho.";
            //}
        }


        private void grvExportList_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContainerValidateEditorEventArgs e)
        {

            var focusRow = GetFocusRow();

            if (grvExportList.FocusedColumn.FieldName == "Quantity")
            {

                var oldQuantity = focusRow.Quantity;

                var newQuantity = Convert.ToDecimal(e.Value);
                if (newQuantity < 0)
                {
                    e.Valid = false;
                    e.ErrorText = "Bạn hãy xem lại số lượng xuất";
                }
                else
                {

                    //var exportedQuantity = GetTotalExportQuantity(focusRow.MerchandiseId, focusRow.IsSaved);

                    //var willBeExportedQuantity = exportedQuantity + ((double)newQuantity - oldQuantity);

                    //var availableQty = focusRow.AvailableExportQuantity;

                    //e.Valid = (willBeExportedQuantity <= availableQty);
                    //if (!e.Valid)
                    //    e.ErrorText = string.Format("Chỉ còn lại {0} mặt hàng",
                    //       (double)newQuantity + (availableQty - willBeExportedQuantity));
                }
            }
        }

        private ExportDetailDTO GetFocusRow()
        {
            var item = grvExportList.GetFocusedRow() as ExportDetailDTO;
            return item;
        }

        private double GetTotalExportQuantity(int merchandiseId, bool isProcessingSavedRecord = false)
        {
            var summaryExportQty = 0d;
            IEnumerable<ExportDetailDTO> items;
            if (!isProcessingSavedRecord)
            {
                items = this.ExportDetails.Where(f => f.MerchandiseId == merchandiseId && !f.IsSaved);
            }
            else
            {
                items = this.ExportDetails.Where(f => f.MerchandiseId == merchandiseId);
            }
            if (items.Count() > 0)
            {
                summaryExportQty = items.Sum(f => f.Quantity);
            }
            return summaryExportQty;
        }

        private void lkCustomer_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Delete)
            {
                lkCustomer.EditValue = 0;
            }
            else if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Plus)
            {
                NewEditCustomer frm = new NewEditCustomer(false);
                frm.OnOperationCompleted = new NewEditCustomer.OperationCompleted(OnCustomerAdded);
                frm.ShowDialog();
            }


        }

        private void OnCustomerAdded(bool success, bool isEditMode)
        {
            _presenter.LoadCustomerList();
        }

        private void txtExportDate_EditValueChanged(object sender, EventArgs e)
        {

        }


        public Guid SelectedExportItem
        {
            get
            {
                var row = GetFocusRow();
                if (row == null) return Guid.Empty;
                return row.Id;
            }
            set
            {
                throw new NotImplementedException();
            }
        }


        public NewEditExport.EditMode CurrentEditMode
        {
            get
            {
                return _editMode;
            }
            set
            {
                _editMode = value;
            }
        }

        private void btnCreateNewExportNumber_Click(object sender, EventArgs e)
        {
            if (_dataChanged && !_dataSaved)
            {
                if (XtraMessageBox.Show("Dữ liệu chưa được lưu, bạn có chắc muốn tạo phiếu xuất mới?", "Tạo phiếu xuất mới", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.No)
                    return;
            }
            _presenter.CreateNewExportNumber();
            //txtExportDate.Enabled = true;
            btnCreateNewExportNumber.Enabled = false;
        }

        private void grvExportList_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            _dataChanged = true;
            _dataSaved = false;
            btnCreateNewExportNumber.Enabled = true;
        }

        private void grvExportList_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            HandleControls();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (XtraMessageBox.Show("Bạn có chắc muốn xóa dòng này?", "Xóa", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == System.Windows.Forms.DialogResult.No)
                return;
            _presenter.DeleteSelectedItem();
            _dataChanged = true;
            _dataSaved = false;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            _presenter.OnExportSaved = new NewEditExportPresenter.ExportSaved(onExportSaved);
            _presenter.SaveExport();
        }

        private void onExportSaved(bool success)
        {
            if (success)
            {
                _dataSaved = true;
                CurrentEditMode = EditMode.EditExisting;
                //txtExportDate.Enabled = false;
                XtraMessageBox.Show("Tất cả thông tin đã được lưu.", "Xuất kho thành công",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                XtraMessageBox.Show("Đã xảy ra lỗi khi xuất kho. Thông tin mới xuất vẫn chưa được lưu và không ảnh hưởng tới dữ liệu cũ, bạn hãy thử lại sau",
                    "Lỗi khi xuất kho", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            if (this.OnExportSaved != null)
                OnExportSaved(success);
        }

        public void RefreshDataControls()
        {
            _presenter.LoadCustomerList();
            _presenter.LoadMerchandiseLookupData(DateTime.Now);
        }


        public int? CustomerId
        {
            get
            {
                if (lkCustomer.EditValue == null || lkCustomer.EditValue.ToString() == "Chọn khách hàng")
                    return null;
                return Convert.ToInt32(lkCustomer.EditValue);
            }
            set
            {
                if (value == null)
                    value = 0;
                lkCustomer.EditValue = value;
            }
        }

        private void lkCustomer_QueryPopUp(object sender, CancelEventArgs e)
        {
            _presenter.LoadCustomerList();
        }

        private void ipeMerchandiseLookup_QueryPopUp(object sender, CancelEventArgs e)
        {

        }

        private void ipeMerchandiseLookup_Popup(object sender, EventArgs e)
        {

        }

        private void NewEditExport_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_dataChanged && !_dataSaved)
            {
                var result = XtraMessageBox.Show("Dữ liệu chưa được lưu, bạn có muốn lưu trước khi đóng không?", "Lưu dữ liệu",
                   MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                if (result == DialogResult.Cancel)
                    e.Cancel = true;
                if (result == System.Windows.Forms.DialogResult.Yes)
                {
                    btnSave_Click(sender, (EventArgs)e);
                }
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();

        }

        private void grvExportList_CellMerge(object sender, DevExpress.XtraGrid.Views.Grid.CellMergeEventArgs e)
        {

        }

        private void ipeMerchandiseLookup_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Plus)
            {
                NewEditMerchandise frm = new NewEditMerchandise();
                frm.OnMerchandiseSaved = new NewEditMerchandise.MerchandiseSavedHandler(OnMerchandiseAdded);
                frm.ShowDialog();
            }
        }

        private void OnMerchandiseAdded(bool success, bool isEdit)
        {
            _presenter.LoadMerchandiseLookupData(DateTime.Today);
        }
    }
}
